package com.demo.redis.configuration;

import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
@Import(RedisPoolProperties.class)
public class RedisConfig {

    @Bean(name = "jedisPoolConfig")
    public JedisPoolConfig jedisPoolConfig(RedisPoolProperties redisPoolProperties) {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(redisPoolProperties.getMaxTotal());
        jedisPoolConfig.setMaxIdle(redisPoolProperties.getMaxIdle());
        jedisPoolConfig.setMinIdle(redisPoolProperties.getMinIdle());
        jedisPoolConfig.setTestOnBorrow(redisPoolProperties.getTestOnBorrow());
        jedisPoolConfig.setTestOnReturn(redisPoolProperties.getTestOnReturn());
        jedisPoolConfig.setFairness(redisPoolProperties.getFairness());
        jedisPoolConfig.setMaxWaitMillis(redisPoolProperties.getMaxWaitMillis());
        jedisPoolConfig.setBlockWhenExhausted(redisPoolProperties.getBlockWhenExhausted());
        return jedisPoolConfig;
    }

    /**
     * 纯jedis 使用pool的配置
     *
     * @param jedisPoolConfig
     * @param redisProperties
     * @return
     */
    @Bean(name = "jedisPool")
    public JedisPool jedisPool(JedisPoolConfig jedisPoolConfig, RedisPoolProperties redisProperties) {
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, redisProperties.getHost(), redisProperties.getPort(), redisProperties.getTimeout(), redisProperties.getPassword(), redisProperties.getDatabase());
        return jedisPool;
    }

    /**
     * 结合spring-data-redis 的配置，可以配置出stringRedisTemplate 或其他的 objectRedisTemplate
     *
     * @param jedisPoolConfig
     * @param redisProperties
     * @return
     */
    @Bean("stringRedisTemplate")
    public RedisTemplate redisTemplate(JedisPoolConfig jedisPoolConfig, RedisPoolProperties redisProperties) {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setDatabase(redisProperties.getDatabase());
        redisStandaloneConfiguration.setHostName(redisProperties.getHost());
        redisStandaloneConfiguration.setPort(redisProperties.getPort());
        redisStandaloneConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword()));
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig);
        jedisConnectionFactory.setHostName(redisStandaloneConfiguration.getHostName());
        jedisConnectionFactory.setPort(redisStandaloneConfiguration.getPort());
        jedisConnectionFactory.setDatabase(redisStandaloneConfiguration.getDatabase());
        RedisTemplate<String, String> stringRedisTemplate = new RedisTemplate<>();
        stringRedisTemplate.setConnectionFactory(jedisConnectionFactory);
        stringRedisTemplate.setKeySerializer(new StringRedisSerializer());
        stringRedisTemplate.setValueSerializer(new FastJsonRedisSerializer<>(String.class));
        return stringRedisTemplate;
    }
}
